package com.fosu.service.impl;

import com.alibaba.fastjson.JSONObject;

import com.fosu.Utils.HttpClientUtil;
import com.fosu.Utils.JwtTokenUtil;
import com.fosu.Utils.Md5Util;
import com.fosu.Utils.RedisUtil;
import com.fosu.common.ResponseResult;
import com.fosu.dao.RoleDao;
import com.fosu.dao.UserAndRoleDao;
import com.fosu.dao.UserDao;
import com.fosu.domain.Role;
import com.fosu.domain.User;
import com.fosu.domain.UserAndRole;
import com.fosu.service.WeChatService;
import com.fosu.vo.UserDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;


import javax.servlet.http.HttpServletResponse;

import java.util.*;

/**
 * @author zqa
 * 微信登录业务
 * @version 1.0
 * @date 2020/10/29 11:23
 */

@Transactional
@Service
public class WeChatServiceImpl implements WeChatService {
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    UserDao userDao;

    @Autowired
    UserAndRoleDao userAndRoleDao;

    @Autowired
    RoleDao roleDao;


    @Override
    public ResponseResult wxLogin(HttpServletResponse resp, JSONObject jsonPram) throws Exception {
        String code = null;
        JSONObject jsonObject1 = null;

        code = jsonPram.getString("code");
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String, String> param = new HashMap<>();
        param.put("appid", "wxcef3c499b30fb541");//wx小程序的id
        param.put("secret", "aebfbb82b0133915ef5fd57d716d2419");//微信小程序的密匙
        param.put("js_code", code);//登录成功的code
        param.put("grant_type", "authorization_code");//grantType固定，默认authorization_code
        try {
            String wxResult = HttpClientUtil.doGet(url, param);//获取到微信session和openId（json格式）
            JSONObject wxSessionModel = JSONObject.parseObject(wxResult);//将wxResult 封装成对象


            if (wxSessionModel == null) {
                return ResponseResult.fail(resp, "code 无效");
            }

            if (wxSessionModel.getInteger("errcode") != null) {
                return ResponseResult.fail(resp, wxSessionModel.getString("errmsg"));
            }


            // 获取参数返回的openid;
            String openId = wxSessionModel.get("openid").toString();
            String md5OpenId = Md5Util.getMD5Str(openId);//对openId进行MD5加密

            //从数据库用户表找user的openid，判断是不是新用户，是新用户存入信息，不是则更新登录时间和上次登录时间
            User user = userDao.findUserByOpenId(md5OpenId);

            if (user != null) {
                Date date = new Date();
                user.setLastLoginTime(user.getLoginTime());//更新上一次登陆时间
                user.setLoginTime(date);  //更新登录时间
                userDao.updateUser(user);
                System.out.println("找到用户");
            } else {
                //将数据存入数据库，创建新用户
                Date date = new Date();
                jsonObject1 = jsonPram.getJSONObject("userInfo");
                user = jsonObject1.toJavaObject(User.class);
                user.setLoginTime(date);  //设置第一次登录时间
                user.setOpenId(md5OpenId);
                userDao.saveUser(user);
            }


            UserDetail userDetail = new UserDetail();  //保存数据到userDetail对象
            userDetail.setOpenId(md5OpenId);
            Set authoritiesSet = new HashSet();
            String roleName = roleDao.findRoleNameByRoleId(3); //从role表中获取“普通用户”角色

            authoritiesSet.add(new SimpleGrantedAuthority(roleName));
            userDetail.setAuthorities(authoritiesSet);
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("id", user.getOpenId());
            System.out.println(user.getOpenId());
            hashMap.put("authorities", authoritiesSet);
            System.out.println(hashMap);


            //利用user的权限和id信息生成token
            String token = JwtTokenUtil.generateToken(userDetail);
            //存入redis
            redisUtil.hset(token, hashMap);
            //返回token和当前登录用户信息给前端
            Map<String, Object> userMap = new HashMap<>();
            userMap.put("token", token);
            userMap.put("userInfo", userDao.findUserByOpenId(md5OpenId));
            return ResponseResult.build(30008, "登录成功", userMap);
        } catch (Exception e) {

            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚 使事务生效
            return ResponseResult.build(30009, "登录失败", null);
        }

    }

}
